/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.commands.connection;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.draw2d.geometry.Point;

import com.cea.papyrus.diagraminterchange2.di2.GraphConnector;
import com.cea.papyrus.diagraminterchange2.di2.GraphEdge;

/**
 * Move an anchor and all edges attached to the anchor.
 * Also move the anchors attached to the edges (indirect recursive call).
 * 
 * @author dumoulin
 */
public class MoveAnchorPositionAndAttachedEdgesCommand {

	/**
	 * The anchor to be moved.
	 */
	GraphConnector anchor;
	
	/**
	 * Old position.
	 */
	private Point oldPosition;
	
	/**
	 * The edges attached to the anchor.
	 */
	List<MoveEndSegmentAnchorsCommand> moveEdgeCommands;
	
	/**
	 * Constructor.
	 * 
	 * @param anchor The anchor to move.
	 */
	public MoveAnchorPositionAndAttachedEdgesCommand(GraphConnector anchor)
	{
		this.anchor = anchor;
	}
	
	/**
	 * save the positions of the node.
	 */
	public void savePositions()
	{
		if(oldPosition!=null)
			return;
		
		
		// save anchor position
		oldPosition = new Point(anchor.getPosition());
		
		// save attached anchors
		Iterator<GraphEdge> iter = getEdges().iterator();
		while(iter.hasNext())
		{
			// lazy creation
			if(moveEdgeCommands == null)
			{
				moveEdgeCommands = new ArrayList<MoveEndSegmentAnchorsCommand>();
			}
			GraphEdge edge = iter.next();
			// Move the end segment
			MoveEndSegmentAnchorsCommand cmd = new MoveEndSegmentAnchorsCommand(anchor, edge);
			moveEdgeCommands.add(cmd);
			cmd.savePositions();
		}
	}

	/*
	 * Restore the positions of the node.
	 */
	/**
	 * 
	 */
	public void restorePositions()
	{

		// Restore position
		anchor.setPosition(oldPosition);
		
		if(moveEdgeCommands==null)
			return;

		// Check lists size
		assert(moveEdgeCommands.size()==getEdges().size());

		// Restore attached edges
		Iterator<MoveEndSegmentAnchorsCommand> saved = moveEdgeCommands.iterator();
		while(saved.hasNext())
		{
			MoveEndSegmentAnchorsCommand cmd = saved.next();
			cmd.restorePositions();
		}
	}

	/**
	 * Move the anchor, and all attached edges.
	 * 
	 * @param newPos 
	 * @param anchor 	 */
	public void moveAnchor(Point newPos)
	{
		// Move the anchor
		anchor.setPosition(newPos);
//		changeAnchorPosition( anchor, newBounds, oldBounds);

		if(moveEdgeCommands==null)
			return;

		// move attached edges
		Iterator<MoveEndSegmentAnchorsCommand> saved = moveEdgeCommands.iterator();
		while(saved.hasNext())
		{
			MoveEndSegmentAnchorsCommand cmd = saved.next();
			cmd.moveSegment(newPos);
		}
	}

	/**
	 * Get the list of anchors of the node.
	 * 
	 * @return 
	 */
	public List getEdges()
	{
		return anchor.getGraphEdge();
	}

	/**
	 * 
	 * 
	 * @return 
	 */
	public Point getOldPosition() {
		// TODO Auto-generated method stub
		return oldPosition;
	}

	
}
